#include "texture.h"
#include "math/MathLib.h"

Texture::Texture()
	: m_Image(NULL)
{
}
Texture::~Texture()
{
	SafeDelete(m_Image);
}


bool Texture::LoadFromFile(const rtString& fileName)
{
	SafeDelete(m_Image);

	rtString dir, name;
	SplitPathName(fileName, dir, name);
	m_Name = name;

	m_Image = Image::CreateFromFile(fileName);
	//if (NULL != m_Image)	// iOrange - ABGR -> RGBA
	//{
	//	uint32* data = reinterpret_cast<uint32*>(m_Image->GetDataPtr());
	//	const int numPixels = m_Image->GetWidth() * m_Image->GetHeight();
	//	for (int i = 0; i < numPixels; ++i)
	//	{
	//		uint32 pixel = data[i];
	//		data[i] = (pixel >> 24) |
	//				  ((pixel << 8) & 0x00FF0000) |
	//				  ((pixel >> 8) & 0x0000FF00) |
	//				  (pixel << 24);
	//	}
	//}

	return (NULL != m_Image);
}

const rtString& Texture::GetName(void) const
{
	return m_Name;
}

const void* Texture::GetDataPtr(void) const
{
	return m_Image->GetDataPtr();
}

uint32 Texture::GetWidth(void) const
{
	return m_Image->GetWidth();
}

uint32 Texture::GetHeight(void) const
{
	return m_Image->GetHeight();
}

rtMath::vec4 Texture::SamplePoint(const rtMath::vec2& st) const
{
	const uint32 width = m_Image->GetWidth();
	const uint32 height = m_Image->GetHeight();

	const int32 ix = static_cast<int32>(st.s * width) % width;
	const int32 iy = static_cast<int32>(st.t * height) % height;

	const uint32* pixels = reinterpret_cast<const uint32*>(m_Image->GetDataPtr());
	return rtMath::uint32_to_vec4(pixels[ix + iy * width]);
}

rtMath::vec4 Texture::SampleBilinear(const rtMath::vec2& st) const
{
	const uint32 width = m_Image->GetWidth();
	const uint32 height = m_Image->GetHeight();

	float m;
	float u = modf(fabs(st.s), &m);
	float v = modf(fabs(st.t), &m);

	const float fu = u * width;
	const float fv = v * height;

	const int32 u00 = static_cast<int32>(fu);
	const int32 u01 = (u00 + 1) % width;
	const int32 u10 = u00;
	const int32 u11 = u01;
	const int32 v00 = static_cast<int32>(fv);
	const int32 v01 = v00;
	const int32 v10 = (v00 + 1) % height;
	const int32 v11 = v10;

	const float ku = fu - u00;
	const float kv = fv - v00;
	const float kuv = ku * kv;

	const float k00 = 1 - ku - kv + kuv;
	const float k01 = ku - kuv;
	const float k10 = kv - kuv;
	const float k11 = kuv;

	const uint32* pixels = reinterpret_cast<const uint32*>(m_Image->GetDataPtr());

	const rtMath::vec4 Color00 = rtMath::uint32_to_vec4(pixels[u00 + v00 * width]);
	const rtMath::vec4 Color01 = rtMath::uint32_to_vec4(pixels[u01 + v01 * width]);
	const rtMath::vec4 Color10 = rtMath::uint32_to_vec4(pixels[u10 + v10 * width]);
	const rtMath::vec4 Color11 = rtMath::uint32_to_vec4(pixels[u11 + v11 * width]);

	return Color00 * k00 + Color01 * k01 + Color10 * k10 + Color11 * k11;
}
